package com.jasperframework.boot.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
  * <p> md5加解密 </p>
  *
  * @site https://miliqkdoc.motopa.cn/
  * @author daizhao
  * @date 2022/12/12 12:12
  */
@Slf4j
public class Md5Util {

    private static final String ALGORITHM = "MD5";

    private static final MessageDigest messageDigest = getMessageDigest();

    /**
     * 密码加密
     *
     * @param rawPass 字符串
     * @return 加密后串
     */
    public static String encode(String rawPass) {
        if (StringUtils.isEmpty(rawPass)) {
            return null;
        }
        //加密后的字符串
        return Base64.encodeBase64String(messageDigest.digest(rawPass.trim().getBytes(StandardCharsets.UTF_8)));
    }

    public static String xiaotaoMd5(String str) {
        try {
            if (StringUtils.isBlank(str)) {
                return null;
            }
            messageDigest.update(str.getBytes(StandardCharsets.UTF_8));
            byte[] digest = messageDigest.digest();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 16; i++) {
                sb.append(String.format("%02x", Byte.valueOf(digest[i])));
            }
            return sb.toString();
        } catch (Exception unused) {
            return null;
        }
    }



    /**
     * 确定计算方法
     *
     * @return
     */
    private static final MessageDigest getMessageDigest() {
        try {
            return MessageDigest.getInstance(ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("No such algorithm [" + ALGORITHM + "]");
        }
    }

    /**
     * <p> MD5加密并转化为十六进制字符</p>
     *
     * @param buf 待加密字符串
     * @return java.lang.String
     * @author daizhao  2018/11/8 15:57
     */
    public static String md5(String buf) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] rs = messageDigest.digest(buf.getBytes(StandardCharsets.UTF_8));
            StringBuffer digestHexStr = new StringBuffer();
            for (int i = 0; i < 16; i++) {
                digestHexStr.append(byteToLowerCaseHex(rs[i]));
            }
            System.out.println("32result = " + digestHexStr);// 32位的加密
            System.out.println("16result = " + digestHexStr.toString().substring(8, 24));// 16位的加密
            return digestHexStr.toString();// 32位的加密
        } catch (Exception e) {
            log.error("MD5加密失败:", e);
        }
        return "";
    }

    /**
     * <p> MD5加密并转化为十六进制字符 ，利用DigestUtils实现</p>
     * @param context 待加密字符串
     * @return java.lang.String
     * @author daizhao  2018/11/8 15:57
     */
    public static String md5Hex(String context) {
        String md5Str = DigestUtils.md5Hex(context);
        System.out.println("32result = " + md5Str);// 32位的加密
        return md5Str;
    }

    /**
     * <p> 将字节转化为十六进制字符（大写字母）</p>
     *
     * @param b 待装好字节
     * @return java.lang.String
     * @author daizhao  2018/11/8 15:58
     */
    private static String byteToUpperCaseHex(byte b) {
        char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        return byteToHex(digit, b);
    }

    /**
     * <p> 将字节转化为十六进制字符（小写字母）</p>
     *
     * @param b
     * @return
     */
    private static String byteToLowerCaseHex(byte b) {
        char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        return byteToHex(digit, b);
    }

    private static String byteToHex(char[] Digit, byte b) {
        char[] ob = new char[2];
        ob[0] = Digit[(b >>> 4) & 0X0F];
        ob[1] = Digit[b & 0X0F];
        String s = new String(ob);
        return s;

    }

    public static void main(String[] args) {
        String token = "78ebc58d4c20dabc1350720b0fd81571";
        String appKey = "24679788";
        String time = "1589098301215";
        String data = "{\"bizType\":\"CommonActivity.getConfigCommon\",\"bizParam\":\"{\\\"activityName\\\":\\\"PC双11直播小窗\\\",\\\"configId\\\":\\\"d135184f089c40ad903c45b801fdb329\\\"}\"}";
        String md5 = token + "&" + time + "&" + appKey + "&" + data;

        System.out.println("md5 = " + md5(md5));
    }

}

